%{

using namespace std;
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "commun.h"

//includes relatifs à notre structure de données
#include "../../parseur/XML/Attribut.h"
#include "../../parseur/XML/Noeud.h"
#include "../../parseur/XML/Texte.h"
#include "../../parseur/XML/Balise.h"

// ces trois fonctions devront changer de nom dans le cas où l'otion -p est utilisée
int xml_wrap(void);
void xml_error(char** nom_DTD,Balise** racine, char *msg);
int xml_lex(void);

%}

%union {
   char * s;
   ElementName * en;  /* le nom d'un element avec son namespace, cf commun.h */
   Balise* balise;
   vector<Attribut*>* vect;
   list<Noeud*>* nodes;
}

%token EGAL SLASH SUP SUPSPECIAL DOCTYPE
%token <s> ENCODING VALEUR DONNEES COMMENT NOM ENNOM
%token <en> OBALISEEN OBALISE OBALISESPECIALE FBALISE FBALISEEN
%type <en> ouvre
%type <balise> element
%type <vect> attributs_opt
%type <nodes> contenu_opt ferme_contenu_et_fin vide_ou_contenu
%parse-param {char** nom_DTD}
%parse-param {Balise** racine}

%%

document
 : declaration_opt element misc_seq_opt {*(racine) = $2;}
 ;
misc_seq_opt
 : misc_seq_opt misc
 | /*vide*/
 ;
misc
 : COMMENT
 ;

declaration_opt
 : declaration
 | /*vide*/
 ;
 
declaration
 : DOCTYPE NOM NOM VALEUR SUP {*(nom_DTD) = $4;}
 ;

element
 : ouvre attributs_opt vide_ou_contenu  {$$ = new Balise($1->second,($3 == 0)); $$->ajouterAttributs($2); if( $3 != 0 ){$$->ajouterListeFils($3);} }
 ;
ouvre
 : OBALISE   {$$ = $1;}
 | OBALISEEN {$$ = $1;}
 ;
vide_ou_contenu
 : SLASH SUP {$$ = 0;}
 | ferme_contenu_et_fin SUP {$$ = $1}
 ;
ferme_contenu_et_fin
 : SUP contenu_opt FBALISE {$$ = $2;}
 ;
contenu_opt 
 : contenu_opt DONNEES {$$ = $1; $$->push_back(new Texte($2));}
 | contenu_opt misc  {$$ = $1;}
 | contenu_opt element {$$ = $1; $$->push_back($2);}
 | /*vide*/ {$$ = new list<Noeud *>();}
 ;
/* I.3.1.1 */
attributs_opt
 : attributs_opt NOM EGAL VALEUR {$$ = $1; $$->push_back(new Attribut(string($2),string($4)));}
 | attributs_opt ENNOM EGAL VALEUR {$$= $1; $$->push_back(new Attribut(string($2),string($4)));}
 | /*vide*/ {$$ = new vector<Attribut*>();}
 ;

%%


/* int main(int argc, char **argv)
{
  int err;

  xml_debug = 1; // pour enlever l'affichage de l'éxécution du parser, commenter cette ligne

  err = xml_parse();
  if (err != 0) printf("Parse ended with %d error(s)\n", err);
  	else  printf("Parse ended with success\n", err);
  return 0;
}
*/


int xml_wrap(void)
{
  return 1;
}

void xml_error(char** nom_DTD, Balise** racine, char *msg)
{
  fprintf(stderr, "%s\n", msg);
}

